package org.moonlight.jvm.instructions.references;

import org.moonlight.jvm.instructions.base.Index16Instruction;
import org.moonlight.jvm.rtda.exclusive.Frame;
import org.moonlight.jvm.rtda.exclusive.OperandStack;
import org.moonlight.jvm.rtda.share.Object;
import org.moonlight.jvm.rtda.share.heap.Class;
import org.moonlight.jvm.rtda.share.heap.symref.ClassRef;
import org.moonlight.jvm.rtda.share.methodarea.RtConstantPool;

/**
 * instanceof: 判断对象是否是某个类的实例（或者对象的类是否实现了某个接口），并把结果推入操作数栈。
 *             instanceof指令需要两个操作数。第一个操作数是uint16索引，从方法的字节码中获取，
 *             通过这个索引可以从当前类的运行时常量池中找到一个类符号引用。
 *             第二个操作数是对象引用，从操作数栈中弹出。
 *
 * @author Moonlight
 * @createTime 2023/8/30 15:41
 **/
public class InstanceOf extends Index16Instruction {

    @Override
    public void execute(Frame frame) {
        // 操作数栈
        OperandStack operandStack = frame.getOperandStack();
        Object ref = operandStack.popRef();
        // 如果引用ref是null的话，不管Class是哪种类型，判断结果都是false
        if (ref == null) {
            operandStack.pushInt(0);
            return;
        }
        RtConstantPool rtCp = frame.getMethod().getClazz().getRtCp();
        ClassRef classRef = (ClassRef) rtCp.getConstant(this.idx);
        Class clazz = classRef.resolvedClass();
        if (ref.isInstanceOf(clazz)) {
            operandStack.pushInt(1);
        } else {
            operandStack.pushInt(0);
        }
    }

}
